home *** CD-ROM | disk | FTP | other *** search
- #include <SetupA4.h>
- #include "xpop.h"
-
- enum { kUnknown, kUncomment, kComment };
-
- XPopRecPtr gPopRec;
-
- void DoInit(void);
- void DoClose(void);
- void DoFOpen(void);
- void DoFClose(void);
- void DoQuery(void);
- void DoIt(void);
-
- Boolean Comment( Handle txt, short language );
- Boolean Uncomment( Handle txt, short language );
- short CountLines( Handle txt );
- void PickComment( short language, short *commentSize, char **comment, char **endcomment );
- /*------------------------------------------------------------*/
- pascal void main( XPopRecPtr paramPtr)
- {
- RememberA0();
- SetUpA4();
-
- gPopRec = paramPtr;
- switch (paramPtr->message) {
- case xpop_init: DoInit(); break;
- case xpop_close: DoClose(); break;
- case xpop_fopen: DoFOpen(); break;
- case xpop_fclose: DoFClose(); break;
- case xpop_query: DoQuery(); break;
- case xpop_doit: DoIt(); break;
- }
- RestoreA4();
- } /* main */
-
- /*---------------*/
- void DoInit(void)
- {
- InitRecPtr initStuff;
- SelectionRecPtr selection;
-
- selection = (SelectionRecPtr) gPopRec->param;
-
- initStuff = (InitRecPtr) NewPtr(sizeof(InitRec));
- if ( initStuff!=NIL ) {
- initStuff->version = 1;
- initStuff-> language = (1 << _c) | (1 << _cplusplus) |
- (1 << _pascal) | (1 << _objectpascal) |
- (1 << _rez) | (1<<_asm);
- initStuff-> writes = true;
- initStuff-> sensitive = true;
- initStuff-> getFileMsgs = false;
- initStuff-> selStuff = kNeedSelection;
- initStuff-> environment = (1 << kMPW) | (1<< kTHINK)| (1<< kGENERIC);
- }
- gPopRec->result = (long) initStuff;
- }
- /*---------------*/
- void DoClose(void)
- {}
- /*---------------*/
- void DoFOpen(void)
- {}
- /*---------------*/
- void DoFClose(void)
- {}
- /*---------------*/
- void DoQuery(void)
- {
- SelectionRecPtr selection;
- short which;
-
- which = kUnknown;
- gPopRec->result = (long) "\pComment(";
-
- selection = (SelectionRecPtr) gPopRec->param;
- if ( selection->selEnd == selection->selStart ||
- selection->hText == NIL ) /* can't comment if it ain't selected */
- return;
-
- switch ( selection->language ) {
- case _c:
- case _cplusplus:
- case _rez:
- if ( **selection->hText == '/' && *( (*selection->hText)+1)=='*' )
- which = kUncomment;
- else
- which = kComment;
- break;
- case _pascal:
- case _objectpascal:
- if ( **selection->hText == '{' )
- which = kUncomment;
- else
- which = kComment;
- break;
- case _asm:
- which = ( **selection->hText == ';' ) ? kUncomment : kComment;
- break;
- } /* switch */
- switch ( which ) {
- case kUncomment: gPopRec->result = (long) "\pUncomment"; break;
- case kComment: gPopRec->result = (long) "\pComment"; break;
- }
- gPopRec->private = which;
- }
- /*---------------*/
- void DoIt(void)
- {
- SelectionRecPtr selection;
- PostDoRecPtr rec;
- Boolean result;
-
- selection = (SelectionRecPtr) gPopRec->param;
- rec = (PostDoRecPtr) NewPtr(sizeof(PostDoRec));
-
- if ( rec ) {
- /* gPopRec->private was set during the query message */
- if ( gPopRec->private == kComment )
- result = Comment( selection->hText, selection->language );
- else
- result = Uncomment( selection->hText, selection->language );
-
- rec->version = 1;
- rec->paste = ( gPopRec->private != 0 && result );
- rec->where = kReplace;
- }
- gPopRec->result = (long) rec;
- }
- /*---------------*/
- Boolean Comment( Handle txt, short language );
- Boolean Comment( Handle txt, short language )
- {
- short commentSize;
- char *comment, *endcomment, *pos, *newPos, *stop;
- short lineCount;
- long len;
- Handle newText;
-
- PickComment( language, &commentSize, &comment, &endcomment );
- lineCount = CountLines( txt );
- len = GetHandleSize( txt );
-
- /* For simplicity, I allocate another handle to put the commented text into.*/
- /* People tight on memory who desire to comment a large block of text will not*/
- /* be happy with this.*/
-
- newText = NewHandle( len + 2 * commentSize * (lineCount+1) + 128 );
- if ( ! newText ) {
- SysBeep(30);
- goto failed;
- }
-
- pos = *txt;
- stop = pos + len;
- newPos = *newText;
-
- /* Comment the beginning */
- BlockMove( comment, newPos, commentSize );
- newPos += commentSize;
-
- /* Comment the middle */
- while ( pos < stop ) {
- while ( *pos!='\r' && pos < stop ) {
- if ( (*pos == *endcomment) && (commentSize==1 || *(pos+1)==*(endcomment+1))) {
- *newPos++ = '»';
- pos += commentSize;
- }
- else
- *newPos++ = *pos++;
- } /* copy and alter line */
-
- if ( pos < stop ) {
- BlockMove( endcomment, newPos, commentSize);
- newPos += commentSize;
- *newPos++ = *pos++;
- }
- if ( pos < stop ) {
- BlockMove( comment, newPos, commentSize);
- newPos+= commentSize;
- }
- }
-
- /* ... and now the end */
- if ( *(newPos-1) != '\r' ) {
- BlockMove( endcomment, newPos, commentSize);
- newPos += commentSize;
- }
-
- /* save the changes */
- len = newPos - *newText;
- HUnlock( txt );
- SetHandleSize( txt, len );
- HLock( txt );
- BlockMove( *newText, *txt, len );
- DisposHandle( newText );
- return true;
- failed:
- return false;
- }
-
- /*---------------*/
- Boolean Uncomment( Handle txt, short language )
- {
- short commentSize;
- char *comment, *endcomment, *pos, *newPos, *stop;
- short lineCount;
- long len;
- Handle newText;
-
- PickComment( language, &commentSize, &comment, &endcomment );
-
- lineCount = CountLines( txt );
- len = GetHandleSize( txt );
-
- newText = NewHandle( len ); /* more than needed */
- if ( ! newText ) {
- SysBeep(30);
- goto failed;
- }
-
- pos = *txt;
- stop = pos + len;
- newPos = *newText;
-
- /* unComment the beginning */
- pos += commentSize;
-
- /* unComment the middle */
- while ( pos < stop ) {
- while ( *pos!='\r' && pos < stop ) {
- if ( *pos=='»' ) {
- BlockMove( endcomment, newPos, commentSize );
- newPos+= commentSize;
- pos++;
- }
- else
- *newPos++ = *pos++;
- } /* copy and alter line */
-
- if ( pos < stop ) {
-
- /* erase the commentend at the end of line */
- if ( (*(pos-commentSize) == *endcomment) && (commentSize==1 || *(pos-1)==*(endcomment+1))) {
- newPos -= commentSize;
- }
-
- *newPos++ = *pos++;
-
- /* skip the comment at the beginning of line */
- if ( (*pos == *comment) && (commentSize==1 || *(pos+1)==*(comment+1)) )
- pos += commentSize;
- }
- }
-
- /* ... and now the end */
- if ( (*(pos-commentSize) == *endcomment) && (commentSize==1 || *(pos-1)==*(endcomment+1))) {
- newPos -= commentSize;
- }
-
- /* save the changes */
- len = newPos - *newText;
- SetHandleSize( txt, len );
- BlockMove( *newText, *txt, len );
- DisposHandle( newText );
- return true;
- failed:
- return false;
- } /* Uncomment */
- /*---------------*/
- short CountLines( Handle txt )
- {
- register char *p,*stop;
- short cnt;
-
- stop = *txt + GetHandleSize(txt);
- for ( p=*txt,cnt=0; p<stop; p++ )
- if (*p=='\r')
- cnt++;
-
- return cnt;
- } /* CountLines() */
- /*----------------*/
- void PickComment( short language, short *commentSize, char **comment, char **endcomment )
- {
- if ( language==_c || language== _cplusplus || language== _rez ) {
- *commentSize = 2;
- *comment = "/*";
- *endcomment = "*/";
- }
- else if ( language==_pascal || language== _objectpascal ) {
- *commentSize = 1;
- *comment = "{";
- *endcomment = "}";
- }
- else if ( language==_asm ) {
- *commentSize = 1;
- *comment = ";";
- *endcomment = " ";
- }
- } /* PickComment */
- /*----------------*/